package be.kdg.bombermanunlimited.client.gui;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.rmi.RemoteException;
import java.util.Vector;

import be.kdg.bombermanunlimited.server.objects.finalclasses.Tile;
import be.kdg.bombermanunlimited.server.remote.interfaces.ITile;
import be.kdg.bombermanunlimited.server.remote.interfaces.ITile.TileType;
/*
 * op de server staat een map, maar het is niet opportuun om alles vanuit de server aan te spreken,
 * daarom lokaal een kopie bijhouden met lokale deelkopien van <GUI_Abstractile> derivaten
 */
public class GUI_Map {
	private Image mapImg;
	private Vector<GUI_AbstractTile> seperateTiles;
	private int size;

	public GUI_Map(Vector<ITile> tiles) {
		seperateTiles = new Vector<GUI_AbstractTile>();
		copyFromServer(tiles);
		size = (int) Math.sqrt(tiles.size());
		constructImg();
	}

	private void copyFromServer(Vector<ITile> tiles) {
		for (int i = 0; i < tiles.size(); i++) {
			// seperateTiles.add(new GUI_AbstractTile(tiles.elementAt(i)));
			try {
				ITile tile = tiles.elementAt(i);

				if (tile.getType() == ITile.TileType.BreakableWall) {
					this.seperateTiles.add(new GUI_BreakableWall(tile));
					// System.out.print("BreakableWall gefiekst! \n");
				} else if (tile.getType() == ITile.TileType.UnbreakableWall) {
					this.seperateTiles.add(new GUI_UnbreakableWall(tile));
					// System.out.print("UNBreakableWall gefiekst! \n");
				} else {
					this.seperateTiles.add(new GUI_Tile(tile));
					// System.out.print("Tile gefiekst! \n");
				}

			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	public Image getMapImg() {
		return mapImg;
	}

	//gaat met de aparte sprites (tile, wall, unbreakableWall, ... ) 1 grote afbeelding 
	//maken als achtergrond. Hierdoor kan door het aanpassen van de *.png image bestanden
	//makkelijk een nieuwe look and feel gecreerd worden
	public void constructImg() {
		//de index die vanuit de SpriteSheet wordt aangeroepen.
		int index;
		SpriteSheet sheet = new SpriteSheet(4, 4, GUI_AbstractTile.TILE_HEIGHT,
				GUI_AbstractTile.TILE_WIDTH, "img/environment.bmp");
		//het aantal blokjes (chunks) dat moet samengegoten worden
		int chunks = seperateTiles.size();
		//maak dus een array met deelimages aan
		BufferedImage[] buffImages = new BufferedImage[chunks];
		
		for (int i = 0; i < chunks; i++) {
			//vraag variablen op die zeggen welke sprite moet geladen worden
			seperateTiles.elementAt(i).getOrientation();
			seperateTiles.elementAt(i).getType();
			
			//kijk welke sprite geladen moet worden
			if (seperateTiles.elementAt(i).getType() == ITile.TileType.Tile) {
				index = 5;
			} else if (seperateTiles.elementAt(i).getType() == ITile.TileType.UnbreakableWall) {
				index = seperateTiles.elementAt(i).getOrientation();
			} else {
				index = 11;
			}
			buffImages[i] = ImageConverter.toBufferedImage(sheet
					.getSprite(index));
		}
		
		//randinfo over welk type image we aanmaken
		int type = buffImages[0].getType();
		int chunkWidth = GUI_AbstractTile.TILE_WIDTH;
		int chunkHeight = GUI_AbstractTile.TILE_HEIGHT;
		//eindbeeld initializeren
		BufferedImage finalImg = new BufferedImage(chunkWidth * size,
				chunkHeight * size, type);

		int num = 0;
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				/*
				 * voegt "vierkantje per vierkantje" de deelbeelden toe aan
				 * het eindbeeld
				 */
				finalImg.createGraphics().drawImage(buffImages[num],
						chunkWidth * j, chunkHeight * i, null);
				num++;
			}
		}
		this.mapImg = finalImg;
	}

	//na explosie van een boompje moet die index een bewandelbare Tile worden
	public void changeTile(int index) {
		this.seperateTiles.remove(index);
		try {
			this.seperateTiles.insertElementAt(new GUI_Tile(new Tile()), index);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		constructImg();
	}
	
	public TileType getTileType(int row, int col) {
		if (row > size || col > size || row < 0 || col < 0
				|| row * size + col > seperateTiles.size()) {
			return TileType.UnbreakableWall;
		} else {
			return seperateTiles.get(size * row + col).getType();
		}
	}
}
